package com.mrd.gtimp.business.service;

import com.mrd.base.BaseBiz;
import com.mrd.exception.FeeException;
import com.mrd.exception.QueryException;
import com.mrd.exception.SaveException;
import com.mrd.gtimp.business.entity.Declaration;
import com.mrd.gtimp.business.entity.DeclarationFree;
import com.mrd.gtimp.business.entity.DeclarationFreeDetail;
import com.mrd.gtimp.business.entity.DeclarationOffer;
import com.mrd.gtimp.business.repository.DeclarationFreeDao;
import com.mrd.gtimp.business.repository.DeclarationFreeDetailDao;
import com.mrd.gtimp.order.entity.DeclaContainer;
import com.mrd.spring.repository.BaseRepository;
import com.mrd.util.KeyGenerator;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

import javax.annotation.Resource;

/**
 * @author xiewl 报关单计费
 */
@Service
public class DeclarationFreeBiz extends BaseBiz<DeclarationFree> {
	private static final org.slf4j.Logger	logger	= LoggerFactory
	        .getLogger(DeclarationFreeBiz.class);
	@Resource
	private DeclarationBiz					declarationBiz;

	@Resource
	private DeclarationFreeDetailDao		declarationFreeDetailDao;

	@Resource
	private DeclarationFreeDao				declarationFreeDao;

	@Resource
	private DeclarationOfferBiz				declarationOfferBiz;

	private DeclarationOffer				declarationOffer;

	@Resource
	// 该处指定注入BaseRepository的dao对象
	@Qualifier("declarationFreeDao")
	public void setBaseRepository(BaseRepository<DeclarationFree, String> baseRepository) {
		super.baseRepository = baseRepository;
	}

	/**
	 * 根据支付id获取结算信息
	 * @param payId
	 *            支付id
	 * @return 结算信息
	 */
	public List<DeclarationFree> findFeeByPayId(String payId) {
		try {
			return declarationFreeDao.findByPay_id(payId);
		} catch (Exception e) {
			logger.error("读取结算信息错误!支付id为:{}", payId, e);
		}
		return new ArrayList<>();
	}

	/**
	 * 根据报关单信息保存结算信息
	 */
	@Transactional
	public DeclarationFree saveFeeForDeclaration(Declaration declaration) throws SaveException {
		if(declaration == null || StringUtils.isEmpty(declaration.getId())) {
			throw new SaveException("报关单为空!");
		}
		String fee = declaration.getDeclaration_free().toString();
		return saveFeeWithUnitAndSumFee(declaration.getId(), fee, fee);
	}

	@Transactional
	public DeclarationFree saveFeeWithUnitAndSumFee(String declarationId, String unitFee, String totalFee){
		DeclarationFree free = declarationFreeDao.findByDeclarationId(declarationId);
		if(free != null){
			declarationFreeDao.delete(free);
		}
		free = new DeclarationFree();
		Declaration declaration = new Declaration();
		declaration.setId(declarationId);
		Random random = new Random();
		int rand = random.nextInt(899999) + 100000;
		String payId = KeyGenerator.generateNoFromDate("P", "yyyyMMddHHmmssS")
				+ Integer.toString(rand);
		free.setPay_id(payId);
		free.setDeclaration(declaration);
		free.setFree(unitFee);
		free.setSum_free(totalFee);
		declarationFreeDao.save(free);
		return free;
	}

	@Transactional
	public void saveFeeWithCommonPayId(String payId, Map<String, String[]> map){
		List<DeclarationFree> feeList = new ArrayList<>();
		for (String declarationId : map.keySet()) {
			DeclarationFree free = new DeclarationFree();
			Declaration declaration = new Declaration();
			declaration.setId(declarationId);
			free.setPay_id(payId);
			free.setDeclaration(declaration);
			String[] feeArray = map.get(declarationId);
			free.setFree(feeArray[0]);
			free.setSum_free(feeArray[1]);
			feeList.add(free);
		}
		declarationFreeDao.save(feeList);
	}

	public String getPayId(){
		Random random = new Random();
		int rand = random.nextInt(899999) + 100000;
		return KeyGenerator.generateNoFromDate("P", "yyyyMMddHHmmssS")
				+ Integer.toString(rand);
	}

	/**
	 * 根据报关单进行报关收费计算(不计算熏蒸,报检)
	 */

	public List<Declaration> countFree(List<Declaration> declarations,
	        List<DeclarationFreeDetail> deFreeDetails) throws FeeException {

		Map<String, DeclarationFreeDetail> detailMap = createDetailsMap(deFreeDetails);
		for(Declaration declaration : declarations) {
			// 获取供应商价格
			declarationOffer = declarationOfferBiz
			        .findValidOffer(declaration.getSupCompany().getId());
			if(declarationOffer == null) {
				throw new FeeException("计费错误，没有报价信息，请联系客服处理!");
			}
			Double fee;
			Integer freeCount;
			if(declaration.getDeclaration_type().equals(Declaration.DECLARATION_TYPE_EXPORT)) {// 出口
				fee = declarationOffer.getDeclaration_amount();
				freeCount = declarationOffer.getContainer_amount();
			} else {// 进口计费
				fee = declarationOffer.getImp_declaration_amount();
				freeCount = declarationOffer.getImp_container_amount();
			}
			if(fee == null || fee == 0) {
				throw new FeeException("计费错误，没有报价信息，请联系客服处理!");
			}
			int containerNum = countContainers(declaration);
			if(containerNum > 0) {// 柜货
				DeclarationFreeDetail detail = detailMap.get("2");// 直航
				if(freeCount != null && freeCount > 0 && containerNum >= freeCount) {// 柜量超过一定的数量免费
					fee = 0.0;
				}
				declaration.setDeclaration_free(fee);
				declaration.setDeclarationFreeDetail(detail);
				declaration.setContainer_num(Integer.toString(containerNum));
			} else {// 散货
				DeclarationFreeDetail detail = detailMap.get("1");
//				fee = declarationOffer.getDeclaration_amount();
				declaration.setDeclaration_free(fee);
				declaration.setDeclarationFreeDetail(detail);
				declaration.setContainer_num("0");
			}
		}
		return declarations;
	}

	/**
	 * 生成项目map
	 */
	private HashMap<String, DeclarationFreeDetail> createDetailsMap(
	        List<DeclarationFreeDetail> details) {
		HashMap<String, DeclarationFreeDetail> map = new HashMap<String, DeclarationFreeDetail>();
		for(DeclarationFreeDetail detail : details) {
			map.put(detail.getType(), detail);
		}
		return map;
	}

	/**
	 * 判断柜货/散货 返回柜数
	 */
	private int countContainers(Declaration declaration) {
		List<DeclaContainer> containers = declaration.getDeclaContainers();
		if(containers != null) {
			Set<String> containerSet = containers.stream()
			        .filter(container -> StringUtils.isNotBlank(container.getContainerNo()))
			        .map(container -> container.getContainerNo().trim())
			        .collect(Collectors.toCollection(TreeSet::new));
			return containerSet.size();
		} else {
			return 0;
		}
		// int num = 0;
		// String containers = declaration.getContainer_no_show();
		// try {
		// if (containers != null && !"".equals(containers)) {
		// ObjectMapper objectMapper = new ObjectMapper();
		// List<Object> list = objectMapper.readValue(containers, List.class);
		// num = list.size();
		// }
		// } catch (JsonParseException e) {
		// e.printStackTrace();
		// } catch (JsonMappingException e) {
		// e.printStackTrace();
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
	}

	/**
	 * @return 计算代理报检
	 */
	private Double declarationCheck(Declaration declaration,DeclarationFreeDetail detail) {
		Double checkFree = new Double(0);
		if("1".equals("1")) {// 表内
			checkFree = new Double(detail.getInner_inspection());
		} else {// 表外
			checkFree = new Double(detail.getOutter_inspection());
		}
		return checkFree;
	}

	/**
	 * 根据报关单id 获取费用
	 */

	public DeclarationFree findEntityByDeclareId(String id) {
		DeclarationFree declarationFree = null;
		try {
			String hql = "from com.mrd.gtimp.business.pojo.DeclarationFree free where free.declaration_id = '"
			        + id + "'";
			declarationFree = (DeclarationFree) findObjectByHql(hql, 0, 10, null).get(0);
			if(declarationFree == null) {
				System.out.println("没有该报关的收费数据");
			}
		} catch (QueryException e) {
			e.printStackTrace();
		}
		return declarationFree;
	}

	public DeclarationOffer getDeclarationOffer() {
		return declarationOffer;
	}

	public void setDeclarationOffer(DeclarationOffer declarationOffer) {
		this.declarationOffer = declarationOffer;
	}

}
